﻿using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using XNAGuiLib.Core.Utilities;

namespace XNAGuiLib.Core.Components
{
    public class Label : GIComponent
    {
        #region Label Protected Field - _rcm
        protected ResourceContentManager _rcm;
        #endregion

        #region Label Protected Field - _assetPrefix
        protected string _assetPrefix;
        #endregion


        #region Label Public Field - Background
        /// <summary>
        /// gets or sets the Background-object used for this label
        /// </summary>
        public Background Background
        {
            get { return (Background)this._gics[0]; }
            set { this._gics[0] = value; }
        }
        #endregion

        #region Label Public Field - BackgroundColor
        /// <summary>
        /// gets or sets the color which is used to draw the label's background value
        /// </summary>
        public Color BackgroundColor
        {
            get { return this.Background.BackgroundTile.ContentComponents[0].ContTexture.ModulationColor; }
            set { this.Background.BackgroundTile.ContentComponents[0].ContTexture.ModulationColor = value; }
        }
        #endregion

        #region Label Public Field - BackgroundOpaque
        /// <summary>
        /// sets the opaque of the background component of the label object
        /// </summary>
        public int BackgroundOpaque
        {
            set
            {
                if (value < 0)
                    Background.Opaque(0);
                if (value > 100)
                    Background.Opaque(100);
                Background.Opaque(value);
            }
        }
        #endregion

        #region Label Public Field - Bounds
        /// <summary>
        /// gets or sets width and height of the label
        /// </summary>
        public new Vector2 Bounds
        {
            get { return new Vector2(this._width, this._height); }
            set { this.Resize((int)value.X, (int)value.Y); }
        }
        #endregion


        #region Label Public Field - Font
        /// <summary>
        /// gets or sets the font which is used to draw  the label's text value
        /// </summary>
        public SpriteFont Font
        {
            get { return this.Text.ContentComponents[0].ContText.Font; }
            set { this.Text.ContentComponents[0].ContText.Font = value; }
        }
        #endregion


        #region Label Public Field - Text
        /// <summary>
        /// gets or sets the GIComponent drawing the text to the screen
        /// </summary>
        public GIComponent Text
        {
            get { return this._gics[1]; }
            set { this._gics[1] = value; }
        }
        #endregion

        #region Label Public Field - TextColor
        /// <summary>
        /// gets or sets the color which is used to draw the label's text value
        /// </summary>
        public Color TextColor
        {
            get { return this.Text.ContentComponents[0].ContText.TextColor; }
            set { this.Text.ContentComponents[0].ContText.TextColor = ColorBlend.ModulateRGB(this.TextColor, value.R, value.G, value.B); }
        }
        #endregion

        #region Label Public Field - TextOpaque
        /// <summary>
        /// sets the Opaque of the labels text
        /// </summary>
        public int TextOpaque
        {
            set
            {
                if (value < 0)
                    Text.Opaque(0);
                if (value > 100)
                    Text.Opaque(100);
                Text.Opaque(value);
            }
        }
        #endregion

        #region Label Public Field - TextValue
        protected string _textValue;
        /// <summary>
        /// gets or sets the text value of this label (stores full value and displays capped value on the label)
        /// </summary>
        public string TextValue
        {
            get { return this._textValue; }
            set
            {
                this._textValue = value;
                this.Text.ContentComponents[0].ContText.Value = TextWrapper.WrapToFit(this._textValue, this.Font, this.Width - (int)this.TextMargin.X, this.Height - (int)this.TextMargin.Y);
                this.UpdateSize();
            }
        }
        #endregion

        #region Label Public Field - TextMargin
        /// <summary>
        /// gets or sets the x- and y-coordinates of the left and top edge of the labels rectangle
        /// </summary>
        public Vector2 TextMargin
        {
            get { return this.Text.RelativePosition; }
            set
            {
                if (!(value.X >= this.Width))
                    this.Text.RelativePosition = new Vector2(value.X, this.Text.RelativePosition.Y);
                if (!(value.Y >= this.Height))
                    this.Text.RelativePosition = new Vector2(this.Text.RelativePosition.X, value.Y);

                this.TextValue = this._textValue;
            }
        }
        #endregion


        public bool _fitHeightToText = false;

        /* Component mapping for the Label Element
         * ============================================
         * [0]  BackgroundTile
         * [1]  Text
         */
        public Label(Game game, ResourceContentManager rcm, string text, int width, int height)
            : base(game)
        {
            this._rcm = rcm;
            // this._assetPrefix = assetPrefix;
            this._width = width;
            this._height = height;
            this._textValue = text;

            this.Add(new Background(game, rcm, "label_", width, height));
            this.Background.UseDecoration = false;

            SpriteFont font = rcm.Load<SpriteFont>("font_default");
            ContentComponent cc_text = new ContentComponent(TextWrapper.WrapToFit(text, font, width, height), font);
            GIComponent gic_text = Provider.GetInstance(game).CreateGIC();
            gic_text.Add(cc_text);
            this.Add(gic_text);
        }


        #region Label Protected Method - Resize(int width, int height)
        /// <summary>
        /// resizes the full label to the given width and height
        /// </summary>
        /// <param name="width">the width of the label</param>
        /// <param name="height">the height of the label</param>
        protected override void Resize(int width, int height)
        {
            this.Text.ContentComponents[0].ContText.Value = TextWrapper.WrapToFit(this._textValue, this.Font, width - (int)this.TextMargin.X, height - (int)this.TextMargin.Y);

            if (_fitHeightToText && _autoScaleHeight)
            {
                height = (int)this.Font.MeasureString(TextWrapper.WrapToFitWidth(this.TextValue, this.Font, width)).Y;
                Console.WriteLine(height);
            }

            this._width = width;
            this._height = height;
            this.Background.Bounds = new Vector2(width, height);
        }
        #endregion


        #region Label Public Method - Opaque(int percentage)
        /// <summary>
        /// set the opaque of the whole label (only child-GICs)
        /// </summary>
        /// <param name="percentage">degree of visibility/opaque</param>
        public new void Opaque(int percentage)
        {
            if (percentage >= 0 && percentage <= 100)
            {
                foreach (GIComponent gic in _gics)
                {
                    gic.Opaque(percentage);
                }
            }
        }
        #endregion
    }
}